(function($) {
	$.fn.Ray_Game = function(options) {
		var target = $(this);
		var params = $.extend({
			width: 300,				
			height: 600,
			scoreLine: 0
		}, options);
		if(undefined != target.data('Ray_Game')){
			var _plugin = $(this).data('Ray_Game');
			_plugin.domMenu.remove();
			_plugin.domScore.remove();
			_plugin.domForm.remove();
			$(window).unbind('resize', _plugin.resetOffset);
			$(this).removeData('Ray_Game');
		} 
		var plugin = new $.Ray_Game(target, params);
		target.data('Ray_Game', plugin);
	};

	$.Ray_Game = function(target, params) {
		var owner = this;
		var offset = target.offset();
		owner.left = offset.left;
		owner.top = offset.top;
		owner.width = params.width;
		owner.height = params.height;
		owner.scoreLine = params.scoreLine;
		owner.plane = new Player(0, 0);
		owner.stones = [];
		owner.stoneSize = 40;
		owner.trailLenth = 30;
		owner.breakPoints = [];
		owner.canvas = target[0];
		owner.canvas.width = owner.width;
		owner.canvas.height = owner.height;
		owner.ctx = owner.canvas.getContext("2d");
		
		owner.num1 = new Image();
		owner.num1.src = "/resource/images/num-1.png";
		owner.num1.left = 155;
		owner.num1.top = 200;
		owner.numData1 = [];
		owner.num1.onload = function(){
			owner.ctx.drawImage(owner.num1, 0, 0);
			var data = owner.ctx.getImageData(0, 0, owner.num1.width, owner.num1.height);
			for(var j=0;j<data.height;j+=1) {
				for(var i=0;i<data.width;i+=1) {
					k=4*(data.width*j+i);
					owner.numData1.push({
						point: new Point(owner.num1.left+i, owner.num1.top+j),
						velocity: {x: Math.random()*8-4, y: Math.random()*8-4},
						r: data.data[k],
						g: data.data[k+1],
						b: data.data[k+2]
					});
				}
			}
			owner.ctx.clearRect(0, 0, owner.width, owner.height);
		};
		owner.num2 = new Image();
		owner.num2.src = "/resource/images/num-2.png";
		owner.num2.left = 145;
		owner.num2.top = 200;
		owner.numData2 = [];
		owner.num2.onload = function(){
			owner.ctx.drawImage(owner.num2, 0, 0);
			var data = owner.ctx.getImageData(0, 0, owner.num2.width, owner.num2.height);
			for(var j=0;j<data.height;j+=1) {
				for(var i=0;i<data.width;i+=1) {
					k=4*(data.width*j+i);
					owner.numData2.push({
						point: new Point(owner.num2.left+i, owner.num2.top+j),
						velocity: {x: Math.random()*8-4, y: Math.random()*8-4},
						r: data.data[k],
						g: data.data[k+1],
						b: data.data[k+2]
					});
				}
			}
			owner.ctx.clearRect(0, 0, owner.width, owner.height);
		};
		owner.num3 = new Image();
		owner.num3.src = "/resource/images/num-3.png";
		owner.num3.left = 145;
		owner.num3.top = 200;
		owner.numData3 = [];
		owner.num3.onload = function(){
			owner.ctx.drawImage(owner.num3, 0, 0);
			var data = owner.ctx.getImageData(0, 0, owner.num3.width, owner.num3.height);
			for(var j=0;j<data.height;j+=1) {
				for(var i=0;i<data.width;i+=1) {
					k=4*(data.width*j+i);
					owner.numData3.push({
						point: new Point(owner.num3.left+i, owner.num3.top+j),
						velocity: {x: Math.random()*8-4, y: Math.random()*8-4},
						r: data.data[k],
						g: data.data[k+1],
						b: data.data[k+2]
					});
				}
			}
			owner.ctx.clearRect(0, 0, owner.width, owner.height);
		};
		
		owner.body = $("body");
		owner.domMenu = $('<div class="gameMenu">'
			+'<a>开始游戏</a>'
			+'<div style="clear: both; height: 10px;"></div>'
			+'<a>查看排名</a>'
			+'<ul></ul></div>');
		owner.body.append(owner.domMenu);
		owner.domMenu.css({
			left: (owner.left+97)+"px",
			top: (owner.top+100)+"px"
		}).slideDown();
		owner.domMenu.find("a").eq(0).click(function(e){
			$(this).parent().hide();
			owner.startGame(e);
		}).end().eq(1).click(function(){
			$.ajax({
				type : "get",
				url : "/blog/ajax/gameScoreList"
					+"?ts="+new Date().getTime(),
				dataType : "json"
			}).done(function(result){
				if(result.isTrue) {
					var domUl = owner.domMenu.find("ul");
					if(result.tag.length==0) {
						domUl.html("<li>暂无排名哦！</li>");
					} else {
						var html = "";
						for(var i=0; i<result.tag.length; i++) {
							var p_s = result.tag[i].split("_");
							html += "<li><label>"+(i+1)+". </label><span>"+p_s[0]+" ["+p_s[1]+"s]</span></li>";
						}
						domUl.html(html);
					}
					if(domUl.is(":hidden")) {
						domUl.slideDown();
					}
				} else {
					$.showAlert(result.message, "确定");
				}
			}).fail(function(){
				$.showAlert("网络繁忙，请稍后再试！", "确定");
			});
		});
		owner.domScore = $('<div class="gameScore">0.00</div>');
		owner.body.append(owner.domScore);
		owner.domScore.css({
			left: owner.left+"px",
			top: owner.top+"px",
			width: (owner.width-20)+"px"
		});
		owner.domForm = $('<div class="gameForm">'
			+'<label>很遗憾，未能上榜！</label>'
			+'<input type="text" value="请留下您的大名" maxlength="10" onkeyup="value=this.value.CHNLength()>10?this.value.CHNSub(10):this.value;" />'
			+'<a>再来一次</a></div>');
		owner.body.append(owner.domForm);
		owner.domForm.find("input").click(function(){
			if($(this).val()=="请留下您的大名") {
				$(this).val("");
			}
		}).end().find("a").click(function(e){
			if(owner.isForm) {
				var name = owner.domForm.find("input").val().trim();
				if(name.length==0) {
					alert("请留下您的大名！");
					return;
				}
				$.ajax({
					type : "post",
					url : "/blog/ajax/gameEnd"
						+"?ts="+new Date().getTime(),
					dataType : "json",
					data : {md5:  params.md5, name: name, score: owner.score.toFixed(2)}
				}).done(function(result){
					if(result.isTrue) {
						owner.domScore.slideUp();
						owner.domForm.hide();
						var html = "";
						for(var i=0; i<result.tag.length; i++) {
							var p_s = result.tag[i].split("_");
							html += "<li><label>"+(i+1)+". </label><span>"+p_s[0]+" ["+p_s[1]+"s]</span></li>";
						}
						owner.domMenu.css({
							left: (owner.left+97)+"px",
							top: (owner.top+100)+"px"
						}).find("ul").html(html).show().end().fadeIn();
					} else {
						$.showAlert(result.message, "确定");
					}
				}).fail(function(){
					$.showAlert("网络繁忙，请稍后再试！", "确定");
				});
			} else {
				owner.domForm.hide();
				owner.startGame(e);
			}
		});
		
		owner.move = function(e){
			owner.plane.position.x = e.clientX-owner.left;
			owner.plane.position.y = e.clientY-owner.top;
		};
		
		owner.resetOffset = function(){
			var offset = target.offset();
			owner.left = offset.left;
			owner.top = offset.top;
			owner.domForm.css({
				left: (owner.left+87)+"px",
				top: (owner.top+160)+"px"
			});
			owner.domMenu.css({
				left: (owner.left+97)+"px",
				top: (owner.top+100)+"px"
			});
			owner.domScore.css({
				left: owner.left+"px",
				top: owner.top+"px"
			});
		};
		$(window).bind('resize', owner.resetOffset);
		
		owner.showStartReady = function(index){
			if(index==3) {
				owner.ctx.drawImage(owner.num3, owner.num3.left, owner.num3.top);
				owner.readyTimer = window.setInterval(function(){
					owner.ctx.clearRect(0, 0, owner.width, owner.height);
					var length = owner.numData3.length;
					for(var obj=null,i=0; i<length; i++) {
						obj=owner.numData3[i];
						obj.velocity.x+=obj.velocity.x*0.01;
						obj.velocity.y+=obj.velocity.y*0.01;
						obj.point.position.x+=obj.velocity.x;
						obj.point.position.y+=obj.velocity.y;
						obj.point.alpha-=0.02;
						owner.ctx.fillStyle="rgba("+obj.r+","+obj.g+","+obj.b+","+obj.point.alpha+")";
						owner.ctx.fillRect(obj.point.position.x,obj.point.position.y,1,1);
						obj.point.alpha<=0&&owner.numData3.splice(i,1);
					}
					owner.plane.trail.push(new Point(owner.plane.position.x,owner.plane.position.y));
					owner.ctx.beginPath();
					owner.ctx.strokeStyle="#CCC";
					owner.ctx.lineWidth = 3;
					var length = owner.plane.trail.length-1;
					for(var d=0; d<length; d++){
						p1=owner.plane.trail[d];
						p2=owner.plane.trail[d+1];
						owner.ctx.quadraticCurveTo(p1.position.x,p1.position.y,p1.position.x+(p2.position.x-p1.position.x)/2,p1.position.y+(p2.position.y-p1.position.y)/2);
						p1.position.y+=2;
					}
					owner.ctx.stroke();
					owner.ctx.closePath();
					owner.plane.trail.length>owner.trailLenth&&owner.plane.trail.shift();
					owner.ctx.beginPath();
					owner.ctx.strokeStyle="#8FF1FF";
					owner.ctx.lineWidth = 2;
					owner.ctx.arc(owner.plane.position.x,owner.plane.position.y,owner.plane.size,Math.PI*5/6,Math.PI*1/6, false);
					owner.ctx.stroke();
					if(owner.numData3.length==0) {
						window.clearInterval(owner.readyTimer);
						owner.showStartReady(2);
					}
				}, 20);
			} else if(index==2) {
				owner.ctx.drawImage(owner.num2, owner.num2.left, owner.num2.top);
				window.setTimeout(function(){
					owner.readyTimer = window.setInterval(function(){
						owner.ctx.clearRect(0, 0, owner.width, owner.height);
						var length = owner.numData2.length;
						for(var obj=null,i=0; i<length; i++) {
							obj=owner.numData2[i];
							obj.velocity.x+=obj.velocity.x*0.01;
							obj.velocity.y+=obj.velocity.y*0.01;
							obj.point.position.x+=obj.velocity.x;
							obj.point.position.y+=obj.velocity.y;
							obj.point.alpha-=0.02;
							owner.ctx.fillStyle="rgba("+obj.r+","+obj.g+","+obj.b+","+obj.point.alpha+")";
							owner.ctx.fillRect(obj.point.position.x,obj.point.position.y,1,1);
							obj.point.alpha<=0&&owner.numData2.splice(i,1);
						}
						if(owner.numData2.length==0) {
							window.clearInterval(owner.readyTimer);
							owner.showStartReady(1);
						}
					}, 20);
				}, 500);
			} else if(index==1) {
				owner.ctx.drawImage(owner.num1, owner.num1.left, owner.num1.top);
				window.setTimeout(function(){
					owner.readyTimer = window.setInterval(function(){
						owner.ctx.clearRect(0, 0, owner.width, owner.height);
						var length = owner.numData1.length;
						for(var obj=null,i=0; i<length; i++) {
							obj=owner.numData1[i];
							obj.velocity.x+=obj.velocity.x*0.01;
							obj.velocity.y+=obj.velocity.y*0.01;
							obj.point.position.x+=obj.velocity.x;
							obj.point.position.y+=obj.velocity.y;
							obj.point.alpha-=0.02;
							owner.ctx.fillStyle="rgba("+obj.r+","+obj.g+","+obj.b+","+obj.point.alpha+")";
							owner.ctx.fillRect(obj.point.position.x,obj.point.position.y,1,1);
							obj.point.alpha<=0&&owner.numData1.splice(i,1);
						}
						if(owner.numData1.length==0) {
							window.clearInterval(owner.readyTimer);
							owner.showStartReady(0);
						}
					}, 20);
				}, 500);
			} else {
				$.ajax({
					type : "post",
					url : "/blog/ajax/gameStart"
						+"?ts="+new Date().getTime(),
					dataType : "json"
				}).done(function(result){
					owner.liveTimer = window.setInterval(owner.draw, 20);
					params.md5 = result.message;
					owner.checkTimer = window.setInterval(function(){
						$.ajax({
							type : "post",
							url : "/blog/ajax/gameCheck"
								+"?ts="+new Date().getTime(),
							dataType : "json",
							data : {md5:  params.md5}
						});
					}, 30000);
				});
			}
		};
		
		owner.planeReady = function(){
			owner.ctx.clearRect(0, 0, owner.width, owner.height);
			owner.plane.trail.push(new Point(owner.plane.position.x,owner.plane.position.y));
			owner.ctx.beginPath();
			owner.ctx.strokeStyle="#CCC";
			owner.ctx.lineWidth = 3;
			var length = owner.plane.trail.length-1;
			for(var d=0; d<length; d++){
				p1=owner.plane.trail[d];
				p2=owner.plane.trail[d+1];
				owner.ctx.quadraticCurveTo(p1.position.x,p1.position.y,p1.position.x+(p2.position.x-p1.position.x)/2,p1.position.y+(p2.position.y-p1.position.y)/2);
				p1.position.y+=2;
			}
			owner.ctx.stroke();
			owner.ctx.closePath();
			owner.plane.trail.length>owner.trailLenth&&owner.plane.trail.shift();
			owner.ctx.beginPath();
			owner.ctx.strokeStyle="#8FF1FF";
			owner.ctx.lineWidth = 2;
			owner.ctx.arc(owner.plane.position.x,owner.plane.position.y,owner.plane.size,Math.PI*5/6,Math.PI*1/6, false);
			owner.ctx.stroke();
		};
		
		owner.startGame = function(e){
			owner.domMenu.hide();
			owner.domScore.html("0.00").css({
				left: owner.left+"px",
				top: owner.top+"px"
			}).slideDown();
			owner.readyTimer = null;
			owner.showStartReady(3);
			$(document).bind("mousemove", owner.move);
			var offset = target.offset();
			owner.left = offset.left;
			owner.top = offset.top;
			owner.plane = new Player(e.clientX-owner.left, e.clientY-owner.top);
			owner.domMenu.hide();
			owner.domScore.html("0.00").css({
				left: owner.left+"px",
				top: owner.top+"px"
			}).slideDown();
			owner.score = 0.00;
		};
		
		owner.draw = function(){ 
			owner.score += 0.01;
			owner.domScore.html(owner.score.toFixed(2));
			owner.ctx.clearRect(0, 0, owner.width, owner.height);
			var stoneNum = owner.stones.length;
			var _stone = owner.addStone();
			stoneNum<owner.stoneSize&&_stone!=null&&owner.stones.push(_stone); 
			for(var d=0;d<stoneNum;d++){
				var stone=owner.stones[d];
				if(stone==null) {
					owner.stones.splice(d,1);
					continue;
				}
				owner.ctx.beginPath();
				owner.ctx.fillStyle="#F66";
				owner.ctx.arc(stone.position.x,stone.position.y,stone.size,0,Math.PI*2,true);
				owner.ctx.fill();
				if(stone.distanceTo(owner.plane.position)<stone.size+owner.plane.size) {
					owner.breakIt(owner.plane.position, 10);
					d=stoneNum;
					break;
				}
				stone.position.y += stone.force;
				if(stone.position.y > owner.height+stone.size){
					owner.stones.splice(d, 1);
				}
			}
			owner.plane.trail.push(new Point(owner.plane.position.x,owner.plane.position.y));
			owner.ctx.beginPath();
			owner.ctx.strokeStyle="#CCC";
			owner.ctx.lineWidth = 3;
			var length = owner.plane.trail.length-1;
			for(var d=0; d<length; d++){
				p1=owner.plane.trail[d];
				p2=owner.plane.trail[d+1];
				owner.ctx.quadraticCurveTo(p1.position.x,p1.position.y,p1.position.x+(p2.position.x-p1.position.x)/2,p1.position.y+(p2.position.y-p1.position.y)/2);
				p1.position.y+=2;
			}
			owner.ctx.stroke();
			owner.ctx.closePath();
			owner.plane.trail.length>owner.trailLenth&&owner.plane.trail.shift();
			owner.ctx.beginPath();
			owner.ctx.strokeStyle="#8FF1FF";
			owner.ctx.lineWidth = 2;
			owner.ctx.arc(owner.plane.position.x,owner.plane.position.y,owner.plane.size,Math.PI*5/6,Math.PI*1/6, false);
			owner.ctx.stroke();
			if(owner.plane.position.x<=0 || owner.plane.position.y<=0 || owner.plane.position.x>=owner.width || owner.plane.position.y>=owner.height) {
				owner.breakIt(owner.plane.position, 10);
			}
		};
		
		owner.breakIt = function(position, offset) {
			window.clearInterval(owner.liveTimer);
			window.clearInterval(owner.checkTimer);
			$(document).unbind("mousemove", owner.move);
			owner.showForm(owner.score);
			owner.breakPoints = [];
			for(var d=10+Math.random()*15; --d>=0;){
				var i=new Point(0, 0);
				i.position.x=position.x+Math.sin(d)*offset;
				i.position.y=position.y+Math.cos(d)*offset;
				i.velocity={x:-4+Math.random()*8,y:-4+Math.random()*8};
				i.alpha=1;
				owner.breakPoints.push(i);
			}
			owner.ctx.clearRect(0, 0, owner.width, owner.height);
			for(var d=0;d<owner.stones.length;d++){
				var stone=owner.stones[d];
				if(stone==null) {
					owner.breakPoints.splice(d,1);
				}
				owner.ctx.beginPath();
				owner.ctx.fillStyle="#F66";
				owner.ctx.arc(stone.position.x,stone.position.y,stone.size,0,Math.PI*2,true);
				owner.ctx.fill();
			}
			owner.deadTimer = window.setInterval(function(){
				owner.ctx.clearRect(0, 0, owner.width, owner.height);
				for(var d=0;d<owner.stones.length;d++){
					var stone=owner.stones[d];
					owner.ctx.beginPath();
					owner.ctx.fillStyle="#F66";
					owner.ctx.arc(stone.position.x,stone.position.y,stone.size,0,Math.PI*2,true);
					owner.ctx.fill();
				}
				for(var d=0;d<owner.breakPoints.length;d++){
					var p=owner.breakPoints[d];
					p.velocity.x+=p.velocity.x*0.04;
					p.velocity.y+=p.velocity.y*0.04;
					p.position.x+=p.velocity.x;
					p.position.y+=p.velocity.y;
					p.alpha-=0.02;
					owner.ctx.fillStyle="rgba(255,255,255,"+Math.max(p.alpha,0)+")";
					owner.ctx.fillRect(p.position.x,p.position.y,1,1);
					p.alpha<=0&&owner.breakPoints.splice(d,1);
				}
				if(owner.breakPoints.length==0) {
					window.clearInterval(owner.deadTimer);
				}
			}, 50);
		};
		
		owner.showForm = function(score){
			if(score>owner.scoreLine) {
				owner.isForm = true;
				owner.domForm.find("label").html("恭喜上榜！").end()
					.find("input").val("请留下您的大名").show().end()
					.find("a").html("提&nbsp;&nbsp;&nbsp;&nbsp;交");
			} else {
				owner.isForm = false;
				owner.domForm.find("label").html("很遗憾，未能上榜！").end()
					.find("input").hide().end()
					.find("a").html("再来一次");
			}
			owner.domForm.css({
				left: (owner.left+87)+"px",
				top: (owner.top+160)+"px"
			}).fadeIn();
		};
		
		owner.addStone = function(){
			var stone = new Enemy();
			if(Math.random()>0.2) {
				stone.position.x=Math.random()*owner.width;
				stone.position.y=-5;
				return stone;
			} else {
				return null;
			}
		};
	};
	
	var Point = function(_x, _y){
		this.position = {
			x: _x,
			y: _y
		};
		this.alpha = 1;
	}
	Point.prototype.distanceTo = function(p) {
		var _x = p.x - this.position.x;
		var _y = p.y - this.position.y;
		return Math.sqrt(_x *_x + _y *_y);
	};
	Point.prototype.clonePosition = function() {
		return {
			x : this.position.x,
			y : this.position.y
		}
	};
	var Player = function(_x, _y){
		this.position = {
			x: _x,
			y: _y
		};
		this.trail = [];
		this.size = 8;
		this.shield = 0;
	};
	Player.prototype = new Point(0, 0);

	var Enemy = function() {
		this.position = {
			x : 0,
			y : 0
		};
		this.size = 3 + Math.random() * 6;
		this.force = 1 + Math.random() * 8;
	}
	Enemy.prototype = new Point(0, 0);

})(jQuery);


